package VWorldGameStudio;

import FCRendering.FCRBattleOrderConstant;
import FCRendering.FCRConstants;
import FCRendering.ImageUtil;
import Function.FCMutilPlayCache;
import lombok.Getter;
import lombok.Setter;
import utils.FCMixUtil;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static FCRendering.FCRMaster.fcv;
import static FCRendering.FCRMaster.tankLib;

/**
 * 怪物属性类
 */
public class FCMonster extends Sprite implements Cloneable {
    // 怪物ID
    @Setter
    @Getter
    private int ID;
    // 怪物名称英文名
    @Setter
    @Getter
    private String name;

    @Setter
    @Getter//中文名
    private String chName;

    // 怪物种类
    @Setter
    @Getter
    private String type; //{ "bionic", "electron", "tank", "biochemistry" };

    @Setter
    @Getter
    private String type2;//"normal"，"elite");， "wanted")， "boss"); 普通，精英，赏金，boss

    @Setter
    @Getter
    private int dangerLevel;//危险等级
    // 奖励金额
    @Setter
    @Getter
    private int money;
    // 怪物血量
    @Setter
    @Getter
    private int blood;
    // 怪物防御
    @Setter
    @Getter
    private int defense;

    @Setter
    @Getter
    private int plateArmour;//防甲

    @Setter
    @Getter
    //命中率值
    private int hitRate;
    // 闪避值
    @Setter
    @Getter
    private int dodge;

    // 速度
    @Setter
    @Getter
    private int speed;

    @Setter
    @Getter//逃跑几率
    private double escape;

    // 奖励经验
    @Setter
    @Getter
    private int experience;

    // 主攻击
    @Setter
    @Getter
    private MstAttack gun1;//如果等于nullj就表示没有这种攻击方式

    @Setter
    @Getter//副攻击
    private MstAttack gun2;//如果等于nullj就表示没有这种攻击方式

    @Setter
    @Getter//特攻击
    private MstAttack gun3;//如果等于nullj就表示没有这种攻击方式

    // 对酸的抗性
    @Setter
    @Getter
    private int acidResistance;
    // 对麻痹的抗性
    @Setter
    @Getter
    private int paralysisResistance;
    // 对毒气的抗性
    @Setter
    @Getter
    private int gasResistance;
    // 对睡眠的抗性
    @Setter
    @Getter
    private int sleepResistance;
    // 对冷冻的抗性
    @Setter
    @Getter
    private int frozenResistance;
    // 对火焰的抗性
    @Setter
    @Getter
    private int fireResistance;

    @Setter
    @Getter    // 触发几率
    private int triggerRate;

    // 掉落物ID
    @Setter
    @Getter
    private String dropItemID;
    // 掉落物几率
    @Setter
    @Getter
    private double dropPro;
    // 怪物材质
    @Setter
    @Getter
    private String pngUrl;

    // 攻击次数
    @Setter
    @Getter
    private double attackTimes = 1;

    @Setter
    @Getter
    private boolean showInBattle = true;

    @Setter
    @Getter
    private int partnerFollow = 0;//同回合中出现的个数

    @Setter
    @Getter
    private boolean escapeState = false;//是不是逃跑了，逃跑的不算入击杀

    // 怪物材质
    public Image getPng() {
        if (pngUrl != null) {
            return Toolkit.getDefaultToolkit().getImage(pngUrl);
        }
        return null;
    }

    /**
     * 指这个怪物拥有什么样的物品，都是用来战斗的，可以是投掷物品，也可以是恢复物品
     * 最多给3个
     */
    @Getter
    private ArrayList<String> keepFcItems = new ArrayList<>(3);

    @Getter
    @Setter
    private int useItemsWeight;//使用道具的权重

    @Getter
    private HashMap<String, FCLongTermState> longTermMap = new HashMap<>();//战斗状态放

    public void addlongTermState(String state, int val, int rounds) {
        FCLongTermState e = longTermMap.get(state);
        if (e != null) {
            //状态叠加吗
            longTermMap.remove(state);
        }
        longTermMap.put(state, new FCLongTermState(state, val, rounds));
    }
    public int getLongTermVal(String state) {
        FCLongTermState e = longTermMap.get(state);
        if (e != null) {
            return e.value;
        }
        return -1;
    }
    //指这个怪死后变身成新的怪物，二阶段，三阶段等
    @Setter
    @Getter
    private String upgradeMonsterID;

    @Setter
    @Getter
    private String depict;//中文描述

    @Getter
    private int showAttackHurtTime = 0;//大于0 的时候要显示伤害

    @Getter
    private int showAttckHurt = 0;//设置了就会显示在头顶战斗界面上

    public void countShowAttactHurtTime(){
        //计算
        if(showAttackHurtTime > 0){
            showAttackHurtTime--;
        }
    }

    public void setShowAttckHurt(int m){
        showAttckHurt = m;
        showAttackHurtTime = 50;
    }

    public void initMonster() {
        if (pngUrl != null) {
            Toolkit.getDefaultToolkit().getImage(pngUrl);
        }
    }

    /**
     * 获取材质尺寸
     *
     * @return
     */
    public int[] getPngSize() {
        try {
            BufferedImage im = ImageIO.read(new File(pngUrl));
            return new int[]{im.getWidth(), im.getHeight()};
        } catch (Exception e) {
            return new int[]{0, 0};
        }
    }

    /**
     * 血量增减,并反馈实际伤害
     *
     * @param hurt
     * @return
     */
    public int addAttack(int hurt) {
        int s = hurt - defense;
        s = Math.max(s, 0);
        blood -= s;
        return s;
    }

    /**
     * 检测是否已死亡
     *
     * @return
     */
    public boolean getIsDeath() {
        return blood < 1;
    }

    /**
     * 克隆
     *
     * @return
     */
    public FCMonster getClone() {
        try {
            return (FCMonster) super.clone();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void endOfRound() {
        ArrayList<FCLongTermState> tmp = new ArrayList<>();
        Iterator<Map.Entry<String, FCLongTermState>> iterator = longTermMap.entrySet().iterator();
        int blood = 0;
        while (iterator.hasNext()) {
            FCLongTermState e = iterator.next().getValue();
            int hurt = 0;
            if (e.stateName.equals(FCRBattleOrderConstant.S_Acid)) {
                //TODO 酸
                hurt = Math.max(4, e.value - e.value * getAcidResistance()/100);
                blood = getBlood() - hurt;
                blood = Math.max(0, blood);
                setBlood(blood);
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 受到酸伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Gas)){
                //TODO 毒气
                hurt = Math.max(4, e.value - e.value * getGasResistance()/100);
                blood = getBlood() - hurt;
                blood = Math.max(0, blood);
                setBlood(blood);
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 受到毒伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Fire)){
                //TODO 火焰
                hurt = Math.max(4, e.value - e.value * getFireResistance()/100);
                blood = getBlood() - hurt;
                blood = Math.max(0, blood);
                setBlood(blood);
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 受到火伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Frozen)){
                //TODO 冰冻
                hurt = Math.max(4, e.value - e.value * getFireResistance()/100);
                blood = getBlood() - hurt;
                blood = Math.max(0, blood);
                setBlood(blood);
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 受到冰冻伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_AddBlood)){
                //TODO 回血
                int bl = getBlood() + e.value;
                bl = Math.max(0, bl);
                setBlood(bl);
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 回血"+bl);
                fcv.showMessage();
            }
            if (e.isRoundEnd()) {
                tmp.add(e);
            }else {
                if(e.stateName.equals(FCRBattleOrderConstant.S_Sleep)){
                    //TODO 睡眠
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 睡眠中无法战斗");
                    fcv.showMessage();
                }else if(e.stateName.equals(FCRBattleOrderConstant.S_Paralysis)){
                    //TODO 麻痹
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 麻痹了无法战斗");
                    fcv.showMessage();
                }else if(e.stateName.equals(FCRBattleOrderConstant.S_Confusion)){
                    //TODO 混乱
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(this) + 1) + "号"+getChName()+" 混乱了");
                    fcv.showMessage();
                }
            }
        }
        for (FCLongTermState s : tmp) {
            longTermMap.remove(s);
        }
    }

    //判断是否在混乱中
    public boolean isMsInConfusion(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Confusion);
        return val != -1;
    }

    public boolean isMsInSleep(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Sleep);
        return val != -1;
    }

    public boolean isMsInParalysis(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Paralysis);
        return val != -1;
    }

    //用于绘制图标的,判断是否有图标的
    public ArrayList<String> getAllLongTermState(){
        ArrayList<String> tmp = new ArrayList<>(0);
        Iterator<Map.Entry<String, FCLongTermState>> iterator = longTermMap.entrySet().iterator();
        while (iterator.hasNext()) {
            FCLongTermState e = iterator.next().getValue();
            if(ImageUtil.checkContainImage(e.stateName)) {
                tmp.add(e.stateName);
            }
        }
        return tmp;
    }

    //获取怪物的闪避率
    public int getMsDogeRate() {
        int isInCement = getLongTermVal(FCRBattleOrderConstant.S_Cement);
        if(isInCement != -1){
            return (int)(dodge/2);
        }
        return dodge;
    }


    //获取怪物的命中率
    public int getHitRate(){
        int isGetFog = getLongTermVal(FCRBattleOrderConstant.S_Fog);
        int msHiteRate = hitRate;
        if(isGetFog != -1){
            msHiteRate = msHiteRate/2;
        }
        return msHiteRate;
    }

    //返回和玩家命中率对比躲闪，返回真实的命中率
    public  int getAttackRate(int playerHitRate) {//命中率
        //首先判断能命中不,玩家的命中率-怪物的闪避率 值越小越难中，
        int msDogeRate = getMsDogeRate();
        int rate = playerHitRate - msDogeRate;
        System.out.println("角色攻击命中率="+playerHitRate+"  怪物闪避率="+msDogeRate);
        return rate;
    }

    //返回怪物防御包括叠加的
    public int getMsDefense() {
        int msdefense = getLongTermVal(FCRBattleOrderConstant.S_Defense);
        msdefense = msdefense == -1 ? 0 : msdefense;
        msdefense += defense;
        return msdefense;
    }

    //返回最低防御值的武器
    public MstAttack getMinDefenseMSAttack(){
        ArrayList<MstAttack> list = new ArrayList<>(0);
        MstAttack msa = getGun1();
        if (msa != null && msa.getDefense() > 0) {
            list.add(msa);
        }
        msa = getGun2();
        if (msa != null && msa.getDefense() > 0) {
            list.add(msa);
        }
        msa = getGun3();
        if (msa != null && msa.getDefense() > 0) {
            list.add(msa);
        }

        MstAttack ret = null;
        for(MstAttack a: list){
            if(ret == null){
                ret = a;
            }else {
                if(a.getDefense() < ret.getDefense()){
                    ret = a;
                }
            }
        }
        return ret;
    }
}
